# -*- coding: utf-8 -*-


# cmap2owl -- Helper application to convert from concept maps to OWL ontologies
# Copyright (c) 2008-2013  Rodrigo Rizzi Starr
#  
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#  
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#  
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.


'''
This file sets up two loggers. A general one, that besides printing to stdout
will append to a global log file, and one specific for the file currently
opened, that will print to stdout and to a file named <openFile>.log.

The logging level may be defined by an input argument switch
(--log=<INFO|DEBUG|WARN|WARNING>) or in the appConfig.ini file.

Errors related to logging are marked with return value 2.

This file needs Python 2.7 because of option captureWarnings.

@author: Rodrigo Rizzi Starr
@copyright: Copyright © 2008-2013 Rodrigo Rizzi Starr
@license: MIT License
@contact: rodrigo.starr@gmail.com
'''


import os
from os.path import join, exists, expandvars
import sys
import logging

# Sanity checks (ensure Python 2.7)
_ver = sys.version_info
if not (_ver.major == 2 and _ver.minor == 7):
    raise Error('This application was tested only in Python 2.7. If you are '
                'trying to use version 2.6, there are some features like '
                'captureWarnings that are not supported.')


# Some global (and hopefully static) info
_loggerErrorExitValue = 2


def _parseLogInputArgs():
    '''Parses the input arguments searching for an argument of the form:
       --log=<INFO|DEBUG|WARN|WARNING>. Return a debug level.

       If no input switch is found, defaults to INFO debug level.
    '''
    
    logLevel = logging.DEBUG
    
    switches = [switch for switch in sys.argv[1:] if switch[:6] == '--log=']
    if len(switches) > 0:
        switch = switches[-1] # If there is more than one switch, the last one
                              # is valid
        value = switch[6:]
        if value == 'DEBUG':
            logLevel = logging.DEBUG
        elif value == 'INFO':
            logLevel = logging.INFO
        elif value == 'WARN' or value == 'WARNING':
            logLevel = logging.WARNING
        else:
            sys.stderr.write('Unknown debugging switch: %s' % value)
            sys.exit(_loggerErrorExitValue)

    return logLevel


def _configureLog():
    '''Sets some default options for the logger.'''

    logFile = join('.', 'cmap2owl.log')
    logLevel = _parseLogInputArgs()

    # Adds some lines to separate sessions in the log file
    with open(logFile, 'at') as f:
        f.write('\n\n\n\n')
    
    # Configures the logger (file & screen)
    logging.captureWarnings(True) # Redirects python warnings to the log
    logger = logging.getLogger()  # root logger
    logger.setLevel(logLevel)
    
    # create file handler which logs even debug messages
    fh = logging.FileHandler(logFile)
    fh.setLevel(logLevel)
    
    # create console handler with the same log level
    ch = logging.StreamHandler()
    ch.setLevel(logLevel)
    
    # create formatter and add it to the handlers
    fmt = logging.Formatter(fmt='%(asctime)s  %(levelname)-8s  %(filename)-30s '
                                '%(lineno)-3s %(funcName)s %(message)s',
                            datefmt='%Y-%m-%d %H:%M:%S')
    ch.setFormatter(fmt)
    fh.setFormatter(fmt)
    
    # add the handlers to logger
    logger.addHandler(ch)
    logger.addHandler(fh)

    # And add the same handlers to the python warnings logger
    pywarningLogger = logging.getLogger('py.warnings')
    pywarningLogger.addHandler(ch)
    pywarningLogger.addHandler(fh)

    return logger


# FIXME: Not implemented yet
## def configureLogFromOptions(optionsDict):
##     '''This function expects a dictionary of options and configures the logger
##        according to the options. No option is required.

##        The options here will override any option defined before, except for
##        logging level.
##     '''

##     log = logging.getLogger() # root logger


# We define a global logger for ease of use
log = _configureLog()
statLog = logging.getLogger('statistics')

def configureStatisticsLogger(fileName):
    if len(statLog.handlers) != 0:
        log.warn('configureStatisticsLogger was called more than once.')
    else:
        # Configure the statistics logger to log to fileName and also to the
        # basic logger
        fh = logging.FileHandler(fileName)
        fh.setLevel(logging.INFO)
        fmt = log.handlers[0].formatter
        fh.setFormatter(fmt)
        
        statLog.addHandler(fh)



